import React from 'react';
import classnames from 'classnames';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { IconProps } from '../Icon';
import Icon from '../Icon';

type InputSize = 'large' | 'small';

// omit 可以忽略某个属性, 使用 omit 嵌套可以忽略多个属性
export interface InputProps
  extends Omit<
    Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>,
    'prefix'
  > {
  disabled?: boolean;
  size?: InputSize;

  // 是否在输入框尾部插入图标
  suffixIcon?: React.ReactElement | IconProp;

  // 是否在输入框前部插入图标
  prefixIcon?: React.ReactElement | IconProp;
  prepend?: string | React.ReactElement | string;
  append?: string | React.ReactElement;
  style?: React.CSSProperties;
  onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
}

export const Input: React.FC<InputProps> = ({
  style,
  prepend,
  append,
  suffixIcon,
  prefixIcon,
  type,
  size,
  disabled,

  ...props
}) => {
  // 取出各种属性
  // 根据属性计算不同的 classnames
  const classes = classnames('input', size && `input--${size}`, {
    'is-disabled': disabled,
    'is-affix': !!suffixIcon || !!prefixIcon,
    'input-group': prepend || append,
    'input-group__has-append': !!append,
    'input-group__has-prepend': !!prepend,
  });

  const genPrefixIcon = () => {
    return typeof prefixIcon === 'string' ? (
      <Icon icon={prefixIcon as IconProp} className='input__prefix' />
    ) : (
      React.cloneElement(
        prefixIcon as React.FunctionComponentElement<IconProps>,
        {
          className: 'input__prefix',
        }
      )
    );
  };

  const genSuffixIcon = () => {
    return typeof suffixIcon === 'string' ? (
      <Icon icon={suffixIcon as IconProp} className='input__suffix' />
    ) : (
      // suffixIcon as React.FunctionComponentElement<IconProps>.type.displayName === 'Icon' &&
      React.cloneElement(
        suffixIcon as React.FunctionComponentElement<IconProps>,
        {
          className: 'input__suffix',
        }
      )
    );
  };
  const fixControlledValue = (value: any) => {
    if (typeof value === 'undefined' || value === null) {
      return '';
    }
    return value;
  };
  if ('value' in props) {
    delete props.defaultValue;
    props.value = fixControlledValue(props.value);
  }

  return (
    // 根据判断是否要添加特定的节点
    <div style={style} className={classes}>
      {prepend && <div className='input-group__prepend'>{prepend}</div>}
      {!prepend && prefixIcon && genPrefixIcon()}
      <input
        type={type}
        className='input__inner'
        disabled={disabled}
        {...props}
      />
      {suffixIcon && genSuffixIcon()}
      {append && <div className='input-group__append'>{append}</div>}
    </div>
  );
};

export default Input;
